home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: DZDisplay.c
- *
- * Contents: Handles the window and its contents.
- *
- * Copyright © 1996 Apple Computer, Inc.
- */
-
- #ifndef USE_DRAW_SPROCKET
- #define USE_DRAW_SPROCKET 1
- #endif
-
- #include <assert.h>
-
- #include <Fonts.h>
- #include <Quickdraw.h>
- #include <Windows.h>
-
- #include <QD3D.h>
- #include <QD3DCamera.h>
- #include <QD3DDrawContext.h>
- #include <QD3DGroup.h>
- #include <QD3DLight.h>
- #include <QD3DMath.h>
- #include <QD3DRenderer.h>
- #include <QD3DShader.h>
- #include <QD3DView.h>
-
- #include "DZDisplay.h"
- #include "DZGame.h"
- #include "DZInput.h"
- #include "DZResource.h"
-
- #if USE_DRAW_SPROCKET
- #include "DrawSprocket.h"
- #endif
-
-
- #if USE_DRAW_SPROCKET
- static DisplayObject gDisplayObject = NULL;
- #else
- static WindowPtr gDisplayWindow = NULL;
- #endif
-
- static Boolean gDisplayActive = false;
-
- static PicHandle gDisplayStartScreen = NULL;
-
- static TQ3ViewObject gDisplayView = NULL;
- static TQ3DrawContextObject gDisplayDrawContext = NULL;
- static TQ3RendererObject gDisplayRenderer = NULL;
- static TQ3CameraObject gDisplayCamera = NULL;
- static TQ3GroupObject gDisplayLightGroup = NULL;
- static TQ3LightObject gDisplayAmbientLight = NULL;
- static TQ3LightObject gDisplayDirectionalLight = NULL;
- static TQ3LightObject gDisplayPointLight = NULL;
- static TQ3ShaderObject gDisplayIllumination = NULL;
-
- //• To get around an Interactive Renderer bug wherein Q3Renderer_Sync
- //• crashes when called on a renderer that has not rendered.
- static Boolean gDisplayHasRendered = false;
-
-
- #if USE_DRAW_SPROCKET
- static Boolean Display_IsBusy(
- DisplayObject inDisplayObject,
- UInt32 inContext);
- #endif
-
- static void Display_RenderImage(
- void);
-
- static void Display_BeginQD(
- void);
-
- static void Display_EndQD(
- void);
-
- static void Display_GetImageArea(
- TQ3Area* outArea);
-
- static float Display_GetImageAspectRatio(
- void);
-
-
- /* =============================================================================
- * Display_Init (external)
- *
- * Creates the display window, initializes QD3D view etc. to draw in it.
- * ========================================================================== */
- void Display_Init(
- void)
- {
- TQ3ViewAngleAspectCameraData viewAngleCameraData;
- TQ3PointLightData pointLightData;
- TQ3ColorRGB white = {1.0, 1.0, 1.0};
-
- // Grab the start screen
- gDisplayStartScreen = GetPicture(kPictID_StartScreen);
-
- // Create the view
- gDisplayView = Q3View_New();
-
- // Set up where to draw
- #if USE_DRAW_SPROCKET
- {
- DisplayConfig theConfig;
- DisplayConfig theActualConfig;
-
- // Create the display
- theConfig.device = NULL;
- theConfig.mode = 0;
- theConfig.frequency = 0;
- theConfig.width = 512;
- theConfig.height = 384;
- theConfig.colorNeeds = kDisplayColorRequest;
- theConfig.colorTable = NULL;
- theConfig.specialFlags = kDisplaySpecialBuffered | kDisplaySpecialQD3DAccel;
- theConfig.specialFlagsInHW = 0;
- theConfig.frontBufferDepthMask = kDisplayDepthMaskAll;
- theConfig.backBufferDepthMask = kDisplayDepthMask32 | kDisplayDepthMask16;
- theConfig.frontBufferBestDepth = 32;
- theConfig.backBufferBestDepth = 32;
- theConfig.pageCount = 2;
- theConfig.reserved1 = 0;
- theConfig.reserved2 = 0;
- FindGDeviceFromConfig(&theConfig);
- NewDisplay(&theConfig, &gDisplayObject);
-
- GetDisplayActualConfig(gDisplayObject, &theActualConfig);
- if (theActualConfig.frontBufferBestDepth < 16)
- {
- //• SHOULD PUT UP AN ALERT HERE SAYING SOMETHING LIKE
- //• "The best monitor setting that DroneZone could find was XXX."
- //• "DroneZone runs much faster in Thousands or Millions of Colors."
- //• "You can run in Thousands or Millions of Colors if you expand"
- //• "the Video RAM on your display card, or if you switch to a smaller"
- //• "video monitor." (OK) (Quit)
- }
-
- // DSp_SetDebugMode(true);
-
- FadeDisplayGamma(NULL, kSmoothFadeOut, NULL);
- SetDisplayPlayState(gDisplayObject, kDisplayPlayStateActive);
- //• SHOW SPLASH SCREEN HERE
- FadeDisplayGamma(NULL, kSmoothFadeIn, NULL);
-
- #if 1
- {
- GWorldPtr theGWorld;
- PixMapHandle pixMapHandle;
- TQ3PixmapDrawContextData pixmapDrawContextData;
- // Create the draw context
- GetDisplayBackBuffer(gDisplayObject, &theGWorld);
- pixMapHandle = GetGWorldPixMap(theGWorld);
-
- pixmapDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor;
- pixmapDrawContextData.drawContextData.clearImageColor.a = 1.0;
- pixmapDrawContextData.drawContextData.clearImageColor.r = 0.0;
- pixmapDrawContextData.drawContextData.clearImageColor.g = 0.0;
- pixmapDrawContextData.drawContextData.clearImageColor.b = 0.0;
- pixmapDrawContextData.drawContextData.paneState = kQ3False;
- pixmapDrawContextData.drawContextData.maskState = kQ3False;
- pixmapDrawContextData.drawContextData.doubleBufferState = kQ3False;
-
- pixmapDrawContextData.pixmap.image = GetPixBaseAddr(pixMapHandle);
- pixmapDrawContextData.pixmap.width = theConfig.width;
- pixmapDrawContextData.pixmap.height = theConfig.height;
- pixmapDrawContextData.pixmap.rowBytes = (*pixMapHandle)->rowBytes & 0x00003FFF;
- pixmapDrawContextData.pixmap.pixelSize = theActualConfig.frontBufferBestDepth;
- pixmapDrawContextData.pixmap.bitOrder = kQ3EndianBig;
- pixmapDrawContextData.pixmap.byteOrder = kQ3EndianBig;
-
- switch (pixmapDrawContextData.pixmap.pixelSize)
- {
- case 16:
- pixmapDrawContextData.pixmap.pixelType = kQ3PixelTypeRGB16;
- break;
-
- case 32:
- pixmapDrawContextData.pixmap.pixelType = kQ3PixelTypeRGB32;
- break;
-
- default:
- assert(0);
- }
-
- gDisplayDrawContext = Q3PixmapDrawContext_New(&pixmapDrawContextData);
- }
- #else
- {
- TQ3MacDrawContextData macDrawContextData;
-
- // Create the draw context
- macDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor;
- macDrawContextData.drawContextData.clearImageColor.a = 1.0;
- macDrawContextData.drawContextData.clearImageColor.r = 0.0;
- macDrawContextData.drawContextData.clearImageColor.g = 0.0;
- macDrawContextData.drawContextData.clearImageColor.b = 0.0;
- macDrawContextData.drawContextData.maskState = kQ3False;
- macDrawContextData.drawContextData.paneState = kQ3False;
- macDrawContextData.drawContextData.doubleBufferState = kQ3False;
- macDrawContextData.library = kQ3Mac2DLibraryNone;
- macDrawContextData.viewPort = NULL;
- macDrawContextData.grafPort = NULL;
-
- GetDisplayBackBuffer(gDisplayObject, &macDrawContextData.window);
-
- gDisplayDrawContext = Q3MacDrawContext_New(&macDrawContextData);
- }
- #endif
- }
- #else
- {
- TQ3MacDrawContextData macDrawContextData;
-
- // Create the window
- gDisplayWindow = GetNewCWindow(kWindID_Display, NULL, (WindowPtr)(-1));
-
- // Create the draw context
- macDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor;
- macDrawContextData.drawContextData.clearImageColor.a = 1.0;
- macDrawContextData.drawContextData.clearImageColor.r = 0.0;
- macDrawContextData.drawContextData.clearImageColor.g = 0.0;
- macDrawContextData.drawContextData.clearImageColor.b = 0.0;
- macDrawContextData.drawContextData.maskState = kQ3False;
- macDrawContextData.library = kQ3Mac2DLibraryNone;
- macDrawContextData.drawContextData.paneState = kQ3True;
- macDrawContextData.drawContextData.doubleBufferState = kQ3True;
- macDrawContextData.window = (CGrafPtr) gDisplayWindow;
-
- Display_GetImageArea(&macDrawContextData.drawContextData.pane);
-
- gDisplayDrawContext = Q3MacDrawContext_New(&macDrawContextData);
- }
- #endif
-
- Q3View_SetDrawContext(gDisplayView, gDisplayDrawContext);
-
- // Create the renderer
- #if 1
- gDisplayRenderer = Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
- Q3InteractiveRenderer_SetDoubleBufferBypass(gDisplayRenderer, kQ3True);
- #else
- gDisplayRenderer = Q3Renderer_NewFromType(kQ3RendererTypeWireframe);
- #endif
-
- Q3View_SetRenderer(gDisplayView, gDisplayRenderer);
-
- // Create the camera
- viewAngleCameraData.cameraData.placement.cameraLocation.x = 0.0;
- viewAngleCameraData.cameraData.placement.cameraLocation.y = 0.0;
- viewAngleCameraData.cameraData.placement.cameraLocation.z = 0.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.x = 1.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.y = 0.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.z = 0.0;
- viewAngleCameraData.cameraData.placement.upVector.x = 0.0;
- viewAngleCameraData.cameraData.placement.upVector.y = 1.0;
- viewAngleCameraData.cameraData.placement.upVector.z = 0.0;
- viewAngleCameraData.cameraData.range.hither = 0.2;
- viewAngleCameraData.cameraData.range.yon = 200.0;
- viewAngleCameraData.cameraData.viewPort.origin.x = -1.0;
- viewAngleCameraData.cameraData.viewPort.origin.y = 1.0;
- viewAngleCameraData.cameraData.viewPort.width = 2.0;
- viewAngleCameraData.cameraData.viewPort.height = 2.0;
- viewAngleCameraData.fov = 1.2;
- viewAngleCameraData.aspectRatioXToY = Display_GetImageAspectRatio();
-
- gDisplayCamera = Q3ViewAngleAspectCamera_New(&viewAngleCameraData);
-
- Q3View_SetCamera(gDisplayView, gDisplayCamera);
-
- // Create the light group
- gDisplayLightGroup = Q3LightGroup_New();
- Q3View_SetLightGroup(gDisplayView, gDisplayLightGroup);
-
- // Create the point light
- pointLightData.lightData.isOn = kQ3True;
- pointLightData.lightData.brightness = 5.0;
- pointLightData.lightData.color = white;
- pointLightData.castsShadows = kQ3True;
- pointLightData.attenuation = kQ3AttenuationTypeInverseDistance;
- pointLightData.location.x = 0.0;
- pointLightData.location.y = 0.0;
- pointLightData.location.z = 0.0;
-
- gDisplayPointLight = Q3PointLight_New(&pointLightData);
-
- Q3Group_AddObject(gDisplayLightGroup, gDisplayPointLight);
-
- // Create the illumination shader
- #if 1
- gDisplayIllumination = Q3PhongIllumination_New();
- #else
- gDisplayIllumination = Q3LambertIllumination_New();
- #endif
- }
-
-
- /* =============================================================================
- * Display_Exit (external)
- *
- * Takes down the window, disposes of the QD3D stuff.
- * ========================================================================== */
- void Display_Exit(
- void)
- {
- if (gDisplayHasRendered)
- {
- Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
- }
-
- #if USE_DRAW_SPROCKET
- if(gDisplayObject != NULL)
- {
- FadeDisplayGamma(NULL, kSmoothFadeOut, NULL);
- SetDisplayPlayState(gDisplayObject, kDisplayPlayStateInactive);
- FadeDisplayGamma(NULL, kSmoothFadeIn, NULL);
- DisposeDisplay(gDisplayObject);
- gDisplayObject = NULL;
- }
- #else
- if (gDisplayWindow != NULL)
- {
- DisposeWindow(gDisplayWindow);
- gDisplayWindow = NULL;
- }
- #endif
-
- if (gDisplayView != NULL)
- {
- Q3Object_Dispose(gDisplayView);
- gDisplayView = NULL;
- }
-
- if (gDisplayDrawContext != NULL)
- {
- Q3Object_Dispose(gDisplayDrawContext);
- gDisplayDrawContext = NULL;
- }
-
- if (gDisplayRenderer != NULL)
- {
- Q3Object_Dispose(gDisplayRenderer);
- gDisplayRenderer = NULL;
- }
-
- if (gDisplayCamera != NULL)
- {
- Q3Object_Dispose(gDisplayCamera);
- gDisplayCamera = NULL;
- }
-
- if (gDisplayLightGroup != NULL)
- {
- Q3Object_Dispose(gDisplayLightGroup);
- gDisplayLightGroup = NULL;
- }
-
- if (gDisplayAmbientLight != NULL)
- {
- Q3Object_Dispose(gDisplayAmbientLight);
- gDisplayAmbientLight = NULL;
- }
-
- if (gDisplayDirectionalLight != NULL)
- {
- Q3Object_Dispose(gDisplayDirectionalLight);
- gDisplayDirectionalLight = NULL;
- }
-
- if (gDisplayPointLight != NULL)
- {
- Q3Object_Dispose(gDisplayPointLight);
- gDisplayPointLight = NULL;
- }
-
- if (gDisplayIllumination != NULL)
- {
- Q3Object_Dispose(gDisplayIllumination);
- gDisplayIllumination = NULL;
- }
- }
-
-
- /* =============================================================================
- * Display_Activate (external)
- *
- * Handles activation and deactivation.
- * ========================================================================== */
- void Display_Activate(
- Boolean inActivate)
- {
- if (gDisplayActive != inActivate)
- {
- gDisplayActive = inActivate;
-
- Input_Activate(inActivate);
-
- if (!gDisplayActive)
- {
- Game_Silence();
- }
-
- if (gDisplayHasRendered)
- {
- Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
- }
-
- Display_DrawGrow();
- }
- }
-
-
- /* =============================================================================
- * Display_IsActive (external)
- *
- * Returns true if the game is active.
- * ========================================================================== */
- Boolean Display_IsActive(
- void)
- {
- #if USE_DRAW_SPROCKET
- return true;
- #else
- return gDisplayActive;
- #endif
- }
-
-
- /* =============================================================================
- * Display_DrawGrow (external)
- *
- * Draws the grow box.
- * ========================================================================== */
- void Display_DrawGrow(
- void)
- {
- #if !USE_DRAW_SPROCKET
- Rect bounds;
-
- SetPort(gDisplayWindow);
-
- // Erase the horizontal part
- bounds = gDisplayWindow->portRect;
- bounds.top = bounds.bottom-15;
-
- EraseRect(&bounds);
-
- // Draw the grow box, but only the horizontal scroll stuff
- ClipRect(&bounds);
- DrawGrowIcon(gDisplayWindow);
- ClipRect(&gDisplayWindow->portRect);
- #endif
- }
-
-
- /* =============================================================================
- * Display_DrawContents (external)
- *
- * Draws the contents of the window.
- * ========================================================================== */
- void Display_DrawContents(
- void)
- {
- TQ3Area area;
- FontInfo fontInfo;
- Rect bounds;
- Rect bounds1;
-
- static Str255 pausedString = "\pPaused"; //• SHOULD COME FROM RESOURCE
-
- switch (Game_GetState())
- {
- case kGameState_Playing:
- Display_RenderImage();
- break;
-
- case kGameState_Paused:
- Display_RenderImage();
- Display_BeginQD();
- Display_GetImageArea(&area);
-
- TextFont(geneva);
- TextFace(bold);
- TextSize(72);
-
- GetFontInfo(&fontInfo);
-
- MoveTo(
- area.min.x + 0.5*(area.min.x + area.max.x - StringWidth(pausedString)),
- area.min.y + 0.5*(area.min.y + area.max.y + fontInfo.ascent));
-
- ForeColor(redColor);
- DrawString(pausedString);
- ForeColor(blackColor);
-
- Display_EndQD();
- break;
-
- case kGameState_Stopped:
- Display_BeginQD();
-
- Display_GetImageArea(&area);
-
- bounds.top = area.min.y;
- bounds.left = area.min.x;
- bounds.bottom = area.max.y;
- bounds.right = area.max.x;
-
- PaintRect(&bounds);
-
- bounds1 = (*gDisplayStartScreen)->picFrame;
- OffsetRect(
- &bounds1,
- ((bounds.right-bounds.left) - (bounds1.right-bounds1.left) >> 1) - bounds1.left,
- ((bounds.bottom-bounds.top) - (bounds1.bottom-bounds1.top) >> 1) - bounds1.top);
-
- DrawPicture(gDisplayStartScreen, &bounds1);
-
- Display_EndQD();
- break;
- }
- }
-
-
- /* =============================================================================
- * Display_RenderImage (internal)
- *
- * Draws the 3D part of the window.
- * ========================================================================== */
- void Display_RenderImage(
- void)
- {
- #if USE_DRAW_SPROCKET
- {
- GWorldPtr theGWorld;
-
- GetDisplayBackBuffer(gDisplayObject, &theGWorld);
- Q3MacDrawContext_SetWindow(gDisplayDrawContext, theGWorld);
- }
- #endif
-
- Q3View_StartRendering(gDisplayView);
- do
- {
- // Set up the rendering state
- Q3InterpolationStyle_Submit(kQ3InterpolationStyleVertex, gDisplayView);
- Q3BackfacingStyle_Submit(kQ3BackfacingStyleFlip, gDisplayView);
- Q3FillStyle_Submit(kQ3FillStyleFilled, gDisplayView);
- Q3Object_Submit(gDisplayIllumination, gDisplayView);
-
- // Draw the game contents
- Game_Submit(gDisplayView);
- }
- while (Q3View_EndRendering(gDisplayView) == kQ3ViewStatusRetraverse);
-
- gDisplayHasRendered = true;
-
- #if USE_DRAW_SPROCKET
- SwapDisplayBuffers(gDisplayObject, Display_IsBusy, 0);
- #endif
- }
-
-
- /* =============================================================================
- * Display_IsBusy (internal)
- *
- * Called by SwapDisplayBuffers (or a VBL task that it kicks off) to determine
- * if the back buffer is finished rendering. Since QD3D can render
- * asynchronously through hardware, we have to let it finish. Unfortunately,
- * the only way to do this is to hang here with a renderer Sync call.
- * ========================================================================== */
- #if USE_DRAW_SPROCKET
- Boolean Display_IsBusy(
- DisplayObject inDisplayObject,
- UInt32 inContext)
- {
- Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
- return false;
- }
- #endif
-
-
- /* =============================================================================
- * Display_Resize (external)
- *
- * Called after the window has changed size.
- * ========================================================================== */
- void Display_Resize(
- void)
- {
- #if !USE_DRAW_SPROCKET
- TQ3Area imageArea;
-
- // Reset the clip
- ClipRect(&gDisplayWindow->portRect);
-
- // Change the draw context
- Display_GetImageArea(&imageArea);
- Q3DrawContext_SetPane(gDisplayDrawContext, &imageArea);
-
- // Change the camera aspect ratio
- Q3ViewAngleAspectCamera_SetAspectRatio(gDisplayCamera, Display_GetImageAspectRatio());
- #endif
- }
-
-
- /* =============================================================================
- * Display_GetWindow (external)
- *
- * Returns our window pointer.
- * ========================================================================== */
- WindowPtr Display_GetWindow(
- void)
- {
- #if USE_DRAW_SPROCKET
- return NULL;
- #else
- return gDisplayWindow;
- #endif
- }
-
-
- /* =============================================================================
- * Display_SetViewerPosition (external)
- *
- * Moves the camera and point light based on the given info.
- * ========================================================================== */
- void Display_SetViewerPosition(
- const TQ3Point3D* inPosition,
- const TQ3Vector3D* inDirection,
- const TQ3Vector3D* inUp)
- {
- TQ3CameraPlacement placement;
-
- assert(inPosition != NULL);
- assert(inDirection != NULL);
- assert(inUp != NULL);
-
- // Move the camera
- placement.cameraLocation = *inPosition;
- placement.upVector = *inUp;
-
- Q3Point3D_Vector3D_Add(inPosition, inDirection, &placement.pointOfInterest);
-
- Q3Camera_SetPlacement(gDisplayCamera, &placement);
-
- // Move the point light
- Q3PointLight_SetLocation(gDisplayPointLight, inPosition);
- }
-
-
- /* =============================================================================
- * Display_GetViewerPosition (external)
- *
- * Returns the current camera position.
- * ========================================================================== */
- void Display_GetViewerPosition(
- TQ3Point3D* outPosition,
- TQ3Vector3D* outDirection,
- TQ3Vector3D* outUp)
- {
- TQ3CameraPlacement placement;
-
- assert(outPosition != NULL);
- assert(outDirection != NULL);
- assert(outUp != NULL);
-
- Q3Camera_GetPlacement(gDisplayCamera, &placement);
-
- *outPosition = placement.cameraLocation;
- *outUp = placement.upVector;
-
- Q3Point3D_Subtract(
- &placement.pointOfInterest,
- &placement.cameraLocation,
- outDirection);
- }
-
-
- /* =============================================================================
- * Display_GetImageArea (internal)
- *
- * Sets outArea to the area occupied by the 3D image part of the window.
- * ========================================================================== */
- void Display_GetImageArea(
- TQ3Area* outArea)
- {
- assert(outArea != NULL);
-
- #if USE_DRAW_SPROCKET
- {
- DisplayConfig theConfig;
-
- GetDisplayConfig(gDisplayObject, &theConfig);
-
- outArea->min.x = 0;
- outArea->max.x = theConfig.width;
- outArea->min.y = 0;
- outArea->max.y = theConfig.height;
- }
- #else
- outArea->min.x = gDisplayWindow->portRect.left;
- outArea->max.x = gDisplayWindow->portRect.right;
- outArea->min.y = gDisplayWindow->portRect.top;
- outArea->max.y = gDisplayWindow->portRect.bottom-15;
- #endif
- }
-
-
- /* =============================================================================
- * Display_GetImageAspectRatio (internal)
- *
- * Returns the aspect ratio of the area occupied by the 3D image part of the
- * window.
- * ========================================================================== */
- float Display_GetImageAspectRatio(
- void)
- {
- TQ3Area imageArea;
-
- Display_GetImageArea(&imageArea);
-
- return (imageArea.max.x-imageArea.min.x) / (imageArea.max.y-imageArea.min.y);
- }
-
-
- /* =============================================================================
- * Display_BeginQD (internal)
- *
- * Sets up for doing Quickdraw drawing.
- * ========================================================================== */
- void Display_BeginQD(
- void)
- {
- if (gDisplayHasRendered)
- {
- Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
- }
-
- #if USE_DRAW_SPROCKET
- ••• TODO •••
- #else
- SetPort(gDisplayWindow);
- #endif
- }
-
-
- /* =============================================================================
- * Display_EndQD (internal)
- *
- * Undoes what Display_BeginQD did.
- * ========================================================================== */
- void Display_EndQD(
- void)
- {
- #if USE_DRAW_SPROCKET
- ••• TODO •••
- #else
- // do nothing
- #endif
- }
-
-
-